Zum Hauptinhalt springen

Übung: Deinen ersten Workflow per TowelScript deployen

Was du in dieser Übung lernst: Du baust einen dreistufigen Workflow vollständig aus Claude Code heraus — schreiben, prüfen, deployen, ausführen, Ergebnis kontrollieren. Dabei durchläufst du zum ersten Mal die komplette Werkzeugkette und siehst, wie sich die Fallstricke aus Einheit 4 in der Praxis bemerkbar machen.

Die API für diese Übung

Wir nutzen dieselbe öffentliche API wie in Kurs 5:

Base URLhttps://69cde52533a09f831b7c9fa5.mockapi.io/api/v1
Ressourcecontacts
EndpunkteGET /contacts, POST /contacts, GET /contacts/:id, PUT /contacts/:id, DELETE /contacts/:id

Ein Kontakt hat die Felder name, company und email.

Hinweis

Die API ist für alle Teilnehmer gemeinsam sichtbar. Lösche deine Testkontakte am Ende wieder — genauso, wie du es mit einem echten Zielsystem tun würdest.

Das Szenario

Eine Anfrage kommt als formloser E-Mail-Text herein. Irgendwo darin steht, wer geschrieben hat, für welche Firma und unter welcher Adresse. Dein Workflow soll daraus einen sauberen Kontakt machen und ihn im Zielsystem anlegen.

[ form ]  →  [ ai ]  →  [ http.post ]
Freitext Absender Kontakt in der
entgegen- extrahieren API anlegen
nehmen

Teil 1: Vorbereiten

Aufgabe 1 — Umgebung prüfen

Lass dir deine Projekte auflisten und merke dir die ID des Projekts, in dem du arbeiten willst.

„Liste meine 42°flow-Projekte auf."

Was passieren sollte

Das Werkzeug project_list liefert eine Liste mit id, name und workflow_count. Wenn hier deine echten Projekte stehen, ist die Verbindung in Ordnung. Kommt eine leere Liste oder ein 401, geh zurück zu Einheit 2.

Aufgabe 2 — Node-Typen nachschlagen

Bevor du schreibst: Welche Node-Typen brauchst du für Formular, KI-Auswertung und REST-Request? Und welche Optionen kennt der Formular-Node?

Mögliche Lösung anzeigen

Aus towelscript_catalog:

AufgabeNode-TypAgent
FormularformAgents::WebFormAgent
KI-AuswertungaiAgents::GenAiAgent
REST-Requesthttp.postAgents::PostAgent

Aus agent_docs mit towelscript_type: "form": secret, form_fields, response_text, custom_css, hmac_secret, ip_allowlist.

Wichtig ist form_fields — ein JSON-Array als String, mit name, label, type je Feld.

Teil 2: Den Quelltext schreiben

Aufgabe 3 — TowelScript formulieren

Schreibe den Workflow. Anforderungen:

  • Das Formular hat ein mehrzeiliges Pflichtfeld freitext
  • Der KI-Node gibt JSON zurück, mit den Feldern name, company, email
  • Der Post-Node sendet einen JSON-Body mit genau diesen drei Feldern — und nichts sonst

Denk an drei Dinge aus Einheit 4: einfache Anführungszeichen für das JSON in form_fields, dreifache für den Prompt, und payload: mit Doppelpunkt.

Mögliche Lösung anzeigen
module academy

flow kontaktanfrage {
node eingang: form {
secret: "academy-kurs6"
form_fields: '[{"name":"freitext","label":"E-Mail-Text einfuegen","type":"textarea","rows":8,"required":true}]'
response_text: "Danke - die Anfrage wird verarbeitet."
}

node extrahieren: ai {
model: "gus:tav"
output_format: "json"
prompt_template: """Extrahiere den Absender aus dem folgenden E-Mail-Text.
Gib ausschliesslich ein JSON-Objekt zurueck, ohne Einleitung und ohne Markdown.

Zielschema:
{"name": "Vor- und Nachname", "company": "Firmenname", "email": "E-Mail-Adresse oder null"}

E-Mail-Text:
{{ freitext }}"""
}

node anlegen: http.post {
post_url: "https://69cde52533a09f831b7c9fa5.mockapi.io/api/v1/contacts"
method: "post"
content_type: "json"
no_merge: true
payload: {
name: "{{ name }}",
company: "{{ company }}",
email: "{{ email }}"
}
}

eingang -> extrahieren -> anlegen
}

Zu den drei Optionen des Post-Nodes, die leicht übersehen werden:

  • content_type: "json" — sonst wird der Body als Formularfelder gesendet
  • no_merge: true — sonst hängt der Agent die komplette eingehende Payload mit an, inklusive last_message und workflow_run_id
  • payload: statt payload — sonst sind die Verbindungen weg

Teil 3: Prüfen, bevor etwas passiert

Aufgabe 4 — Die Prüfkette durchlaufen

Lass den Quelltext prüfen — mit allen drei Werkzeugen, nicht nur mit check.

„Prüfe diesen TowelScript-Quelltext mit check, compile und graph."

Worauf du achten musst

towelscript_check liefert:

{ "valid": true, "errors": [], "warnings": [],
"stats": { "lines": 37, "nodes": 3, "flows": 1, "modules": 1 } }

nodes: 3 — stimmt.

towelscript_graph liefert:

{ "flows": [ { "name": "kontaktanfrage",
"edges": [
{ "from": "eingang", "to": "extrahieren", "kind": "data" },
{ "from": "extrahieren", "to": "anlegen", "kind": "data" }
] } ] }

Zwei Kanten. Wäre edges leer, hättest du irgendwo einen Block ohne Doppelpunkt.

towelscript_compile zeigt die Optionen, die wirklich am Agent landen. Prüfe hier besonders den Post-Node — steht payload dort als verschachteltes Objekt?

"payload": {
"company": "{{ company }}",
"email": "{{ email }}",
"name": "{{ name }}"
}

Wenn name, company und email stattdessen direkt neben post_url stehen, hast du die Blockschreibweise erwischt.

Aufgabe 5 — Den falschen Weg einmal bewusst gehen

Ändere payload: { in payload { und lass erneut prüfen. Notiere, was jedes der drei Werkzeuge meldet.

Mögliche Lösung anzeigen
WerkzeugMeldung
towelscript_checkvalid: true, keine Fehler, keine Warnungen
towelscript_graphedges: []
towelscript_compilelinks: [], und name/company/email liegen flach neben post_url

Das ist die Lehre dieser Übung: check allein ist wertlos für diese Fehlerklasse. Wärst du nur nach valid: true gegangen, hättest du drei unverbundene Agents deployt und den Fehler erst Stunden später im Log gesucht.

Teil 4: Deployen und ausführen

Aufgabe 6 — Deployen

„Deploye das als neuen Workflow mit dem Namen Übung 6 — Kontaktanfrage in Projekt <deine ID>."

Was zurückkommt
{
"success": true,
"workflow_id": 134,
"workflow_name": "Übung 6 — Kontaktanfrage",
"agent_count": 3,
"message": "Workflow deployed with 3 agents"
}

Merk dir die workflow_id — du brauchst sie für alles Weitere.

Öffne den Workflow jetzt einmal im Designer. Die Agents liegen wahrscheinlich übereinander: TowelScript ordnet nichts an. Dass die Verbindungen stimmen, siehst du trotzdem.

Aufgabe 7 — Struktur gegenprüfen

Lass dir den deployten Workflow zeigen und vergleiche mit deiner Absicht.

Worauf du achten musst

workflow_show liefert pro Agent sources und receivers. Die Kette muss durchgehen:

Agentsourcesreceivers
eingangextrahieren
extrahiereneinganganlegen
anlegenextrahieren

Außerdem fällt auf: Das Formular-Secret steht als "[REDACTED]" da. Der Server gibt Geheimnisse nicht heraus — auch nicht an dich. Dazu mehr in Einheit 11.

Aufgabe 8 — Echt ausführen

Starte den Workflow mit einem realistischen E-Mail-Text.

„Führe Workflow <ID> aus, mit diesem Freitext: …"

Nimm zum Beispiel:

Hallo zusammen,

wir hatten uns auf der Messe in Hannover kurz unterhalten. Ich wuerde gern ein
Angebot fuer die Automatisierung unserer Rechnungseingangspruefung bekommen.

Viele Gruesse
Dr. Anke Reinhardt
Leiterin Digitalisierung
Nordwerk Praezisionstechnik GmbH
a.reinhardt@nordwerk-pt.example
Was passieren sollte

workflow_run liefert sofort:

{
"run_id": "0b1abc97-c4ae-4483-b736-695d3375805f",
"status": "queued",
"entry_agent": { "id": 1900, "name": "eingang" },
"entry_message_id": 29213
}

queued, nicht completed — der Workflow läuft asynchron weiter. Die run_id ist dein Faden durch alles, was jetzt folgt.

Aufgabe 9 — Ergebnis prüfen

Kontrolliere auf zwei Wegen: im Workflow und im Zielsystem.

Mögliche Lösung anzeigen

Im Workflowagent_messages auf den KI-Agent zeigt, was die Extraktion geliefert hat:

{
"name": "Dr. Anke Reinhardt",
"company": "Nordwerk Präzisionstechnik GmbH",
"email": "a.reinhardt@nordwerk-pt.example",
"last_message": { "freitext": "Hallo zusammen, …" },
"workflow_run_id": "0b1abc97-…"
}

Beachte: Die drei Felder liegen oben, nicht unter generation — das bewirkt output_format: "json". Und die ursprüngliche Payload ist unter last_message erhalten.

Die KI hat außerdem „Praezisionstechnik" zu „Präzisionstechnik" korrigiert. Ob das erwünscht ist, ist eine fachliche Entscheidung — festhalten solltest du es auf jeden Fall.

Im Logagent_logs auf den Post-Agent zeigt den tatsächlich gesendeten Request:

Preparing POST request to https://69cde52533a09f831b7c9fa5.mockapi.io/api/v1/contacts
headers: {"Content-Type" => "application/json; charset=utf-8"}
Full request: {method: "POST", …, body: "{\"company\":\"Nordwerk Präzisionstechnik GmbH\",
\"email\":\"a.reinhardt@nordwerk-pt.example\",\"name\":\"Dr. Anke Reinhardt\"}"}
Received response status 201

201 — angelegt. Und der Body enthält genau drei Felder, weil no_merge: true gesetzt ist.

Im Zielsystem — ein GET auf die API zeigt den neuen Kontakt.

Teil 5: Aufräumen

Aufgabe 10 — Testdaten entfernen

Lösche deinen Testkontakt aus der API. Den Workflow kannst du behalten — du brauchst ihn in Einheit 10 und in der zweiten Übung wieder.

Vor dem Löschen exportieren

Wenn du einen Workflow doch löschen willst: workflow_export liefert das vollständige JSON. Sichere es. workflow_delete hat keinen Papierkorb.

Was du jetzt kannst

  • Node-Typen und Optionen nachschlagen, statt zu raten
  • Einen vollständigen Workflow in TowelScript schreiben
  • Die Prüfkette checkcompilegraph durchlaufen und den Unterschied benennen
  • Deployen, ausführen und das Ergebnis auf drei Ebenen kontrollieren: Nachricht, Log, Zielsystem

Weiter: Einheit 6 — Die Prüfkette: check, compile, graph